/* eslint-disable react/jsx-props-no-spreading */
import React from 'react';
import {
  Input,
  Button,
  Icon,
  Table,
} from 'antd';
import Highlighter from 'react-highlight-words';

/**
 * HOC for Table component that returns a table with search
 * @param {*} WrappedTable should be Table component from 'antd'
 * NOTE: columns with customized render function, or those with 'disableSearch' set to true,
 *  won't be able to be searched on.
 */
const withSearch = (WrappedTable) => class extends React.Component {
  constructor() {
    super();
    this.state = {
      searchText: '',
      searchedColumn: '',
    };
  }

    getColumnSearchProps = (dataIndex) => ({
      filterDropdown: ({
        setSelectedKeys,
        selectedKeys,
        confirm,
        clearFilters,
      }) => (
        <div style={{ padding: 8 }}>
          <Input
            ref={(node) => {
              this.searchInput = node;
            }}
            placeholder={`Search ${dataIndex}`}
            value={selectedKeys[0]}
            onChange={(e) => setSelectedKeys(e.target.value ? [e.target.value] : [])}
            onPressEnter={() => this.handleSearch(selectedKeys, confirm)}
            style={{ width: 188, marginBottom: 8, display: 'block' }}
          />
          <Button
            type="primary"
            onClick={() => this.handleSearch(selectedKeys, confirm, dataIndex)}
            icon="search"
            size="small"
            style={{ width: 90, marginRight: 8 }}
          >
            Search
          </Button>
          <Button
            onClick={() => this.handleReset(clearFilters)}
            size="small"
            style={{ width: 90 }}
          >
            Reset
          </Button>
        </div>
      ),
      filterIcon: (filtered) => (
        <Icon type="search" style={{ color: filtered ? '#1890ff' : undefined }} />
      ),
      onFilter: (value, record) => record[dataIndex]
        .toString()
        .toLowerCase()
        .includes(value.toLowerCase()),
      onFilterDropdownVisibleChange: (visible) => {
        if (visible) {
          setTimeout(() => this.searchInput.select());
        }
      },
      render: (text) => {
        const { searchText, searchedColumn } = this.state;
        if (searchedColumn === dataIndex) {
          return (
            <Highlighter
              highlightStyle={{ backgroundColor: '#ffc069', padding: 0 }}
              searchWords={[searchText]}
              autoEscape
              textToHighlight={text.toString()}
            />
          );
        }
        return text;
      },
    });

    handleSearch = (selectedKeys, confirm, dataIndex) => {
      confirm();
      this.setState({
        searchText: selectedKeys[0],
        searchedColumn: dataIndex,
      });
    };

    handleReset = (clearFilters) => {
      clearFilters();
      this.setState({ searchText: '' });
    };

    render() {
      const { columns } = this.props;
      const newColumns = columns.map((item) => {
        if (item.render || item.disableSearch) {
          return item;
        }
        return { ...item, ...this.getColumnSearchProps(item.key) };
      });
      const newProps = {
        ...this.props,
        columns: newColumns,
      };
      return <WrappedTable {...newProps} />;
    }
};


export default withSearch(Table);
